mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Ruby: Include subclasses in more API calls
Change the behaviour of `API::getInstance()` and `API::getReturn()` to include results on subclasses of the current API node.
This commit is contained in:
@@ -88,12 +88,14 @@ module API {
|
||||
* This predicate may have multiple results when there are multiple constructor calls invoking this API component.
|
||||
* Consider using `getAnInstantiation()` if there is a need to distinguish between individual constructor calls.
|
||||
*/
|
||||
Node getInstance() { result = this.getASuccessor(Label::instance()) }
|
||||
Node getInstance() { result = this.getASubclass().getASuccessor(Label::instance()) }
|
||||
|
||||
/**
|
||||
* Gets a node representing the result of calling a method on the receiver represented by this node.
|
||||
*/
|
||||
Node getReturn(string method) { result = this.getASuccessor(Label::return(method)) }
|
||||
Node getReturn(string method) {
|
||||
result = this.getASubclass().getASuccessor(Label::return(method))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `new` call to the function represented by this API component.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
classMethodCalls
|
||||
| test1.rb:58:1:58:8 | Use getMember("M1").getMember("C1").getReturn("m") |
|
||||
| test1.rb:59:1:59:8 | Use getMember("M2").getMember("C3").getReturn("m") |
|
||||
instanceMethodCalls
|
||||
| test1.rb:61:1:61:12 | Use getMember("M1").getMember("C1").instance.getReturn("m") |
|
||||
| test1.rb:62:1:62:12 | Use getMember("M2").getMember("C3").instance.getReturn("m") |
|
||||
13
ruby/ql/test/library-tests/dataflow/api-graphs/ApiGraphs.ql
Normal file
13
ruby/ql/test/library-tests/dataflow/api-graphs/ApiGraphs.ql
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Tests of the public API of API Graphs
|
||||
*/
|
||||
|
||||
import codeql.ruby.ApiGraphs
|
||||
|
||||
query predicate classMethodCalls(API::Node node) {
|
||||
node = API::getTopLevelMember("M1").getMember("C1").getReturn("m")
|
||||
}
|
||||
|
||||
query predicate instanceMethodCalls(API::Node node) {
|
||||
node = API::getTopLevelMember("M1").getMember("C1").getInstance().getReturn("m")
|
||||
}
|
||||
@@ -32,6 +32,11 @@ Outer::Inner.foo #$ use=getMember("Outer").getMember("Inner").getReturn("foo")
|
||||
|
||||
module M1
|
||||
class C1
|
||||
def self.m
|
||||
end
|
||||
|
||||
def m
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,4 +53,10 @@ end
|
||||
|
||||
C2 #$ use=getMember("C2") use=getMember("M1").getMember("C1").getASubclass()
|
||||
M2::C3 #$ use=getMember("M2").getMember("C3") use=getMember("M1").getMember("C1").getASubclass()
|
||||
M2::C4 #$ use=getMember("M2").getMember("C4") use=getMember("C2").getASubclass() use=getMember("M1").getMember("C1").getASubclass().getASubclass()
|
||||
M2::C4 #$ use=getMember("M2").getMember("C4") use=getMember("C2").getASubclass() use=getMember("M1").getMember("C1").getASubclass().getASubclass()
|
||||
|
||||
M1::C1.m #$ use=getMember("M1").getMember("C1").getReturn("m")
|
||||
M2::C3.m #$ use=getMember("M2").getMember("C3").getReturn("m") use=getMember("M1").getMember("C1").getASubclass().getReturn("m")
|
||||
|
||||
M1::C1.new.m #$ use=getMember("M1").getMember("C1").instance.getReturn("m")
|
||||
M2::C3.new.m #$ use=getMember("M2").getMember("C3").instance.getReturn("m")
|
||||
|
||||
Reference in New Issue
Block a user