mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge pull request #15503 from github/koesie10/ruby-access-paths
Ruby: Add query for access paths in model editor
This commit is contained in:
89
ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql
Normal file
89
ruby/ql/src/utils/modeleditor/FrameworkModeAccessPaths.ql
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @name Fetch a subset of valid access paths of input and output parameters of a method (framework mode).
|
||||
* @description A list of access paths for input and output parameters of a method. Excludes test and generated code.
|
||||
* @kind table
|
||||
* @id ruby/utils/modeleditor/framework-mode-access-paths
|
||||
* @tags modeleditor access-paths framework-mode
|
||||
*/
|
||||
|
||||
private import ruby
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import queries.modeling.internal.Util as Util
|
||||
|
||||
predicate simpleParameters(string type, string path, string value, DataFlow::Node node) {
|
||||
exists(DataFlow::MethodNode methodNode, DataFlow::ParameterNode paramNode |
|
||||
methodNode.getLocation().getFile() instanceof Util::RelevantFile and
|
||||
(
|
||||
// Check that this parameter belongs to this method
|
||||
// Block parameter explicitly excluded because it's already included
|
||||
// as part of the blockArguments predicate
|
||||
paramNode = Util::getAnyParameter(methodNode) and
|
||||
paramNode != methodNode.getBlockParameter()
|
||||
)
|
||||
|
|
||||
Util::pathToMethod(methodNode, type, path) and
|
||||
value = Util::getArgumentPath(paramNode) and
|
||||
node = paramNode
|
||||
)
|
||||
}
|
||||
|
||||
predicate blockArguments(string type, string path, string value, DataFlow::Node node) {
|
||||
exists(DataFlow::MethodNode methodNode, DataFlow::CallNode callNode |
|
||||
methodNode.getLocation().getFile() instanceof Util::RelevantFile and
|
||||
callNode = methodNode.getABlockCall()
|
||||
|
|
||||
(
|
||||
exists(DataFlow::VariableAccessNode argNode, int i |
|
||||
argNode = callNode.getPositionalArgument(i)
|
||||
|
|
||||
value = "Argument[block].Parameter[" + i + "]" and
|
||||
node = argNode
|
||||
)
|
||||
or
|
||||
exists(DataFlow::ExprNode argNode, string keyword |
|
||||
argNode = callNode.getKeywordArgument(keyword)
|
||||
|
|
||||
value = "Argument[block].Parameter[" + keyword + ":]" and
|
||||
node = argNode
|
||||
)
|
||||
or
|
||||
value = "Argument[block]" and
|
||||
node = callNode
|
||||
) and
|
||||
Util::pathToMethod(methodNode, type, path)
|
||||
)
|
||||
}
|
||||
|
||||
predicate returnValue(string type, string path, string value, DataFlow::Node node) {
|
||||
exists(DataFlow::MethodNode methodNode, DataFlow::Node returnNode |
|
||||
methodNode.getLocation().getFile() instanceof Util::RelevantFile and
|
||||
returnNode = methodNode.getAReturnNode()
|
||||
|
|
||||
Util::pathToMethod(methodNode, type, path) and
|
||||
value = "ReturnValue" and
|
||||
node = returnNode
|
||||
)
|
||||
}
|
||||
|
||||
predicate inputAccessPaths(
|
||||
string type, string path, string value, DataFlow::Node node, string defType
|
||||
) {
|
||||
simpleParameters(type, path, value, node) and defType = "parameter"
|
||||
or
|
||||
blockArguments(type, path, value, node) and defType = "parameter"
|
||||
}
|
||||
|
||||
predicate outputAccessPaths(
|
||||
string type, string path, string value, DataFlow::Node node, string defType
|
||||
) {
|
||||
simpleParameters(type, path, value, node) and defType = "parameter"
|
||||
or
|
||||
blockArguments(type, path, value, node) and defType = "parameter"
|
||||
or
|
||||
returnValue(type, path, value, node) and defType = "return"
|
||||
}
|
||||
|
||||
query predicate input = inputAccessPaths/5;
|
||||
|
||||
query predicate output = outputAccessPaths/5;
|
||||
@@ -0,0 +1,75 @@
|
||||
input
|
||||
| A | Method[bar] | Argument[0] | lib/mylib.rb:13:11:13:11 | x | parameter |
|
||||
| A | Method[bar] | Argument[self] | lib/mylib.rb:13:3:14:5 | self in bar | parameter |
|
||||
| A | Method[foo] | Argument[0] | lib/mylib.rb:7:11:7:11 | x | parameter |
|
||||
| A | Method[foo] | Argument[1] | lib/mylib.rb:7:14:7:14 | y | parameter |
|
||||
| A | Method[foo] | Argument[2] | lib/mylib.rb:7:17:7:20 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[block] | lib/mylib.rb:8:5:8:32 | call to call | parameter |
|
||||
| A | Method[foo] | Argument[block] | lib/mylib.rb:10:5:10:26 | yield ... | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:8:16:8:16 | x | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:10:11:10:11 | x | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:8:19:8:19 | y | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:10:14:10:14 | y | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:8:28:8:31 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:10:23:10:26 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[key1:] | lib/mylib.rb:7:17:7:20 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[self] | lib/mylib.rb:7:3:11:5 | self in foo | parameter |
|
||||
| A! | Method[new] | Argument[0] | lib/mylib.rb:4:18:4:18 | x | parameter |
|
||||
| A! | Method[new] | Argument[1] | lib/mylib.rb:4:21:4:21 | y | parameter |
|
||||
| A! | Method[new] | Argument[self] | lib/mylib.rb:4:3:5:5 | self in initialize | parameter |
|
||||
| A! | Method[self_foo] | Argument[0] | lib/mylib.rb:16:21:16:21 | x | parameter |
|
||||
| A! | Method[self_foo] | Argument[1] | lib/mylib.rb:16:24:16:24 | y | parameter |
|
||||
| A! | Method[self_foo] | Argument[self] | lib/mylib.rb:16:3:17:5 | self in self_foo | parameter |
|
||||
| A::ANested | Method[foo] | Argument[0] | lib/mylib.rb:25:13:25:13 | x | parameter |
|
||||
| A::ANested | Method[foo] | Argument[1] | lib/mylib.rb:25:16:25:16 | y | parameter |
|
||||
| A::ANested | Method[foo] | Argument[self] | lib/mylib.rb:25:5:26:7 | self in foo | parameter |
|
||||
| B | Method[foo] | Argument[0] | lib/other.rb:6:11:6:11 | x | parameter |
|
||||
| B | Method[foo] | Argument[1] | lib/other.rb:6:14:6:14 | y | parameter |
|
||||
| B | Method[foo] | Argument[self] | lib/other.rb:6:3:7:5 | self in foo | parameter |
|
||||
| M1 | Method[foo] | Argument[0] | lib/module.rb:2:11:2:11 | x | parameter |
|
||||
| M1 | Method[foo] | Argument[1] | lib/module.rb:2:14:2:14 | y | parameter |
|
||||
| M1 | Method[foo] | Argument[self] | lib/module.rb:2:3:3:5 | self in foo | parameter |
|
||||
| M1! | Method[self_foo] | Argument[0] | lib/module.rb:5:21:5:21 | x | parameter |
|
||||
| M1! | Method[self_foo] | Argument[1] | lib/module.rb:5:24:5:24 | y | parameter |
|
||||
| M1! | Method[self_foo] | Argument[self] | lib/module.rb:5:3:6:5 | self in self_foo | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[0] | other_lib/lib/other_gem.rb:3:17:3:17 | x | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[1] | other_lib/lib/other_gem.rb:3:20:3:20 | y | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[self] | other_lib/lib/other_gem.rb:3:9:4:11 | self in foo | parameter |
|
||||
output
|
||||
| A | Method[bar] | Argument[0] | lib/mylib.rb:13:11:13:11 | x | parameter |
|
||||
| A | Method[bar] | Argument[self] | lib/mylib.rb:13:3:14:5 | self in bar | parameter |
|
||||
| A | Method[foo] | Argument[0] | lib/mylib.rb:7:11:7:11 | x | parameter |
|
||||
| A | Method[foo] | Argument[1] | lib/mylib.rb:7:14:7:14 | y | parameter |
|
||||
| A | Method[foo] | Argument[2] | lib/mylib.rb:7:17:7:20 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[block] | lib/mylib.rb:8:5:8:32 | call to call | parameter |
|
||||
| A | Method[foo] | Argument[block] | lib/mylib.rb:10:5:10:26 | yield ... | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:8:16:8:16 | x | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[0] | lib/mylib.rb:10:11:10:11 | x | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:8:19:8:19 | y | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[1] | lib/mylib.rb:10:14:10:14 | y | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:8:28:8:31 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[block].Parameter[key2:] | lib/mylib.rb:10:23:10:26 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[key1:] | lib/mylib.rb:7:17:7:20 | key1 | parameter |
|
||||
| A | Method[foo] | Argument[self] | lib/mylib.rb:7:3:11:5 | self in foo | parameter |
|
||||
| A | Method[foo] | ReturnValue | lib/mylib.rb:10:5:10:26 | yield ... | return |
|
||||
| A! | Method[new] | Argument[0] | lib/mylib.rb:4:18:4:18 | x | parameter |
|
||||
| A! | Method[new] | Argument[1] | lib/mylib.rb:4:21:4:21 | y | parameter |
|
||||
| A! | Method[new] | Argument[self] | lib/mylib.rb:4:3:5:5 | self in initialize | parameter |
|
||||
| A! | Method[self_foo] | Argument[0] | lib/mylib.rb:16:21:16:21 | x | parameter |
|
||||
| A! | Method[self_foo] | Argument[1] | lib/mylib.rb:16:24:16:24 | y | parameter |
|
||||
| A! | Method[self_foo] | Argument[self] | lib/mylib.rb:16:3:17:5 | self in self_foo | parameter |
|
||||
| A::ANested | Method[foo] | Argument[0] | lib/mylib.rb:25:13:25:13 | x | parameter |
|
||||
| A::ANested | Method[foo] | Argument[1] | lib/mylib.rb:25:16:25:16 | y | parameter |
|
||||
| A::ANested | Method[foo] | Argument[self] | lib/mylib.rb:25:5:26:7 | self in foo | parameter |
|
||||
| B | Method[foo] | Argument[0] | lib/other.rb:6:11:6:11 | x | parameter |
|
||||
| B | Method[foo] | Argument[1] | lib/other.rb:6:14:6:14 | y | parameter |
|
||||
| B | Method[foo] | Argument[self] | lib/other.rb:6:3:7:5 | self in foo | parameter |
|
||||
| M1 | Method[foo] | Argument[0] | lib/module.rb:2:11:2:11 | x | parameter |
|
||||
| M1 | Method[foo] | Argument[1] | lib/module.rb:2:14:2:14 | y | parameter |
|
||||
| M1 | Method[foo] | Argument[self] | lib/module.rb:2:3:3:5 | self in foo | parameter |
|
||||
| M1! | Method[self_foo] | Argument[0] | lib/module.rb:5:21:5:21 | x | parameter |
|
||||
| M1! | Method[self_foo] | Argument[1] | lib/module.rb:5:24:5:24 | y | parameter |
|
||||
| M1! | Method[self_foo] | Argument[self] | lib/module.rb:5:3:6:5 | self in self_foo | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[0] | other_lib/lib/other_gem.rb:3:17:3:17 | x | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[1] | other_lib/lib/other_gem.rb:3:20:3:20 | y | parameter |
|
||||
| OtherLib::A | Method[foo] | Argument[self] | other_lib/lib/other_gem.rb:3:9:4:11 | self in foo | parameter |
|
||||
@@ -0,0 +1 @@
|
||||
utils/modeleditor/FrameworkModeAccessPaths.ql
|
||||
@@ -1,13 +1,13 @@
|
||||
| lib/module.rb:1:1:7:3 | M1 | mylib | M1 | | | false | module.rb | |
|
||||
| lib/module.rb:2:3:3:5 | foo | mylib | M1 | foo | (x,y) | false | module.rb | |
|
||||
| lib/module.rb:5:3:6:5 | self_foo | mylib | M1! | self_foo | (x,y) | false | module.rb | |
|
||||
| lib/mylib.rb:3:1:30:3 | A | mylib | A | | | false | mylib.rb | |
|
||||
| lib/mylib.rb:3:1:33:3 | A | mylib | A | | | false | mylib.rb | |
|
||||
| lib/mylib.rb:4:3:5:5 | initialize | mylib | A! | new | (x,y) | false | mylib.rb | |
|
||||
| lib/mylib.rb:7:3:8:5 | foo | mylib | A | foo | (x,y,key1:) | false | mylib.rb | |
|
||||
| lib/mylib.rb:10:3:11:5 | bar | mylib | A | bar | (x) | false | mylib.rb | |
|
||||
| lib/mylib.rb:13:3:14:5 | self_foo | mylib | A! | self_foo | (x,y) | false | mylib.rb | |
|
||||
| lib/mylib.rb:21:3:29:5 | ANested | mylib | A::ANested | | | false | mylib.rb | |
|
||||
| lib/mylib.rb:22:5:23:7 | foo | mylib | A::ANested | foo | (x,y) | false | mylib.rb | |
|
||||
| lib/mylib.rb:7:3:11:5 | foo | mylib | A | foo | (x,y,key1:) | false | mylib.rb | |
|
||||
| lib/mylib.rb:13:3:14:5 | bar | mylib | A | bar | (x) | false | mylib.rb | |
|
||||
| lib/mylib.rb:16:3:17:5 | self_foo | mylib | A! | self_foo | (x,y) | false | mylib.rb | |
|
||||
| lib/mylib.rb:24:3:32:5 | ANested | mylib | A::ANested | | | false | mylib.rb | |
|
||||
| lib/mylib.rb:25:5:26:7 | foo | mylib | A::ANested | foo | (x,y) | false | mylib.rb | |
|
||||
| lib/other.rb:3:1:8:3 | B | mylib | B | | | false | other.rb | |
|
||||
| lib/other.rb:6:3:7:5 | foo | mylib | B | foo | (x,y) | false | other.rb | |
|
||||
| lib/other.rb:10:1:12:3 | C | mylib | C | | | false | other.rb | |
|
||||
|
||||
@@ -5,6 +5,9 @@ class A
|
||||
end
|
||||
|
||||
def foo(x, y, key1:, **kwargs, &block)
|
||||
block.call(x, y, key2: key1)
|
||||
|
||||
yield x, y, key2: key1
|
||||
end
|
||||
|
||||
def bar(x, *args)
|
||||
|
||||
Reference in New Issue
Block a user