Skip to content

Commit e95b546

Browse files
committed
Ruby: use Dataflow for Pathname instead of TypeTracking
1 parent f9b952f commit e95b546

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
private import codeql.ruby.AST
44
private import codeql.ruby.ApiGraphs
55
private import codeql.ruby.Concepts
6-
private import codeql.ruby.DataFlow
76
private import codeql.ruby.dataflow.FlowSummary
8-
private import codeql.ruby.dataflow.internal.DataFlowDispatch
97
private import codeql.ruby.frameworks.data.ModelsAsData
10-
private import codeql.ruby.typetracking.TypeTracker
8+
private import codeql.ruby.dataflow.internal.DataFlowImplForLibraries
119

1210
/**
1311
* Modeling of the `Pathname` class from the Ruby standard library.
@@ -29,34 +27,34 @@ module Pathname {
2927
* Every `PathnameInstance` is considered to be a `FileNameSource`.
3028
*/
3129
class PathnameInstance extends FileNameSource, DataFlow::Node {
32-
PathnameInstance() { this = pathnameInstance() }
30+
PathnameInstance() { any(PathnameConfiguration c).hasFlowTo(this) }
3331
}
3432

35-
private DataFlow::LocalSourceNode pathnameInstance(TypeTracker t) {
36-
t.start() and
37-
(
33+
private class PathnameConfiguration extends Configuration {
34+
PathnameConfiguration() { this = "PathnameConfiguration" }
35+
36+
override predicate isSource(DataFlow::Node source) {
3837
// A call to `Pathname.new`.
39-
result = API::getTopLevelMember("Pathname").getAnInstantiation()
38+
source = API::getTopLevelMember("Pathname").getAnInstantiation()
4039
or
4140
// Class methods on `Pathname` that return a new `Pathname`.
42-
result = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",])
43-
or
44-
// Instance methods on `Pathname` that return a new `Pathname`.
45-
exists(DataFlow::CallNode c | result = c |
46-
c.getReceiver() = pathnameInstance() and
41+
source = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",])
42+
}
43+
44+
override predicate isSink(DataFlow::Node sink) { any() }
45+
46+
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
47+
exists(DataFlow::CallNode c | node2 = c |
48+
c.getReceiver() = node1 and
4749
c.getMethodName() =
4850
[
4951
"+", "/", "basename", "cleanpath", "expand_path", "join", "realpath",
5052
"relative_path_from", "sub", "sub_ext", "to_path"
5153
]
5254
)
53-
)
54-
or
55-
exists(TypeTracker t2 | result = pathnameInstance(t2).track(t2, t))
55+
}
5656
}
5757

58-
private DataFlow::Node pathnameInstance() { pathnameInstance(TypeTracker::end()).flowsTo(result) }
59-
6058
/** A call where the receiver is a `Pathname`. */
6159
class PathnameCall extends DataFlow::CallNode {
6260
PathnameCall() { this.getReceiver() instanceof PathnameInstance }

ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ pathnameInstances
5757
| Pathname.rb:39:12:39:19 | foo_path |
5858
| Pathname.rb:41:1:41:3 | p08 |
5959
| Pathname.rb:42:1:42:3 | p01 |
60+
| file://:0:0:0:0 | parameter position 0 of + |
61+
| file://:0:0:0:0 | parameter self of + |
62+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[cleanpath] |
63+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[expand_path] |
64+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[realpath] |
65+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[relative_path_from] |
66+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub_ext] |
67+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[to_path] |
68+
| file://:0:0:0:0 | parameter self of sub |
69+
| file://:0:0:0:0 | parameter self of to_s |
6070
fileSystemAccesses
6171
| Pathname.rb:26:12:26:24 | call to open | Pathname.rb:26:12:26:19 | foo_path |
6272
| Pathname.rb:28:11:28:22 | call to opendir | Pathname.rb:28:11:28:14 | pwd1 |
@@ -123,6 +133,16 @@ fileNameSources
123133
| Pathname.rb:39:12:39:19 | foo_path |
124134
| Pathname.rb:41:1:41:3 | p08 |
125135
| Pathname.rb:42:1:42:3 | p01 |
136+
| file://:0:0:0:0 | parameter position 0 of + |
137+
| file://:0:0:0:0 | parameter self of + |
138+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[cleanpath] |
139+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[expand_path] |
140+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[realpath] |
141+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[relative_path_from] |
142+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[sub_ext] |
143+
| file://:0:0:0:0 | parameter self of ;Pathname;Method[to_path] |
144+
| file://:0:0:0:0 | parameter self of sub |
145+
| file://:0:0:0:0 | parameter self of to_s |
126146
fileSystemReadAccesses
127147
| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:24 | call to read |
128148
fileSystemWriteAccesses

0 commit comments

Comments
 (0)