Skip to content

Commit c5904b7

Browse files
committed
Add inline tests for API Graph subclassing
1 parent 517f2d0 commit c5904b7

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

ruby/ql/lib/codeql/ruby/ApiGraphs.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ module API {
160160
/**
161161
* Gets a path of the given `length` from the root to this node.
162162
*/
163-
private string getAPath(int length) {
163+
string getAPath(int length) {
164164
this instanceof Impl::MkRoot and
165165
length = 0 and
166166
result = ""
@@ -174,8 +174,7 @@ module API {
174174
// avoid producing strings longer than 1MB
175175
result.length() < 1000 * 1000
176176
)
177-
) and
178-
length in [1 .. Impl::distanceFromRoot(this)]
177+
)
179178
}
180179

181180
/** Gets the shortest distance from the root to this node in the API graph. */

ruby/ql/test/library-tests/dataflow/api-graphs/test1.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,23 @@ module Inner
2929
end
3030

3131
Outer::Inner.foo #$ use=getMember("Outer").getMember("Inner").getReturn("foo")
32+
33+
module M1
34+
class C1
35+
end
36+
end
37+
38+
class C2 < M1::C1 #$ use=getMember("M1").getMember("C1")
39+
end
40+
41+
module M2
42+
class C3 < M1::C1 #$ use=getMember("M1").getMember("C1")
43+
end
44+
45+
class C4 < C2 #$ use=getMember("C2")
46+
end
47+
end
48+
49+
C2 #$ use=getMember("C2") use=getMember("M1").getMember("C1").getASubclass()
50+
M2::C3 #$ use=getMember("M2").getMember("C3") use=getMember("M1").getMember("C1").getASubclass()
51+
M2::C4 #$ use=getMember("M2").getMember("C4") use=getMember("C2").getASubclass() use=getMember("M1").getMember("C1").getASubclass().getASubclass()

ruby/ql/test/library-tests/dataflow/api-graphs/use.ql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ class ApiUseTest extends InlineExpectationsTest {
3030
element = n.toString()
3131
)
3232
}
33+
34+
// We also permit optional annotations for any other path on the line.
35+
// This is used to test subclass paths, which typically have a shorter canonical path.
36+
override predicate hasOptionalResult(Location location, string element, string tag, string value) {
37+
exists(API::Node a, DataFlow::Node n | relevantNode(a, n, location) |
38+
tag = "use" and
39+
element = n.toString() and
40+
value = a.getAPath(_)
41+
)
42+
}
3343
}
3444

3545
private int size(AstNode n) { not n instanceof StmtSequence and result = count(n.getAChild*()) }

0 commit comments

Comments
 (0)