3
3
private import codeql.ruby.AST
4
4
private import codeql.ruby.ApiGraphs
5
5
private import codeql.ruby.Concepts
6
- private import codeql.ruby.DataFlow
7
6
private import codeql.ruby.dataflow.FlowSummary
8
- private import codeql.ruby.dataflow.internal.DataFlowDispatch
9
7
private import codeql.ruby.frameworks.data.ModelsAsData
10
- private import codeql.ruby.typetracking.TypeTracker
8
+ private import codeql.ruby.dataflow.internal.DataFlowImplForLibraries
11
9
12
10
/**
13
11
* Modeling of the `Pathname` class from the Ruby standard library.
@@ -29,34 +27,34 @@ module Pathname {
29
27
* Every `PathnameInstance` is considered to be a `FileNameSource`.
30
28
*/
31
29
class PathnameInstance extends FileNameSource , DataFlow:: Node {
32
- PathnameInstance ( ) { this = pathnameInstance ( ) }
30
+ PathnameInstance ( ) { any ( PathnameConfiguration c ) . hasFlowTo ( this ) }
33
31
}
34
32
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 ) {
38
37
// A call to `Pathname.new`.
39
- result = API:: getTopLevelMember ( "Pathname" ) .getAnInstantiation ( )
38
+ source = API:: getTopLevelMember ( "Pathname" ) .getAnInstantiation ( )
40
39
or
41
40
// 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
47
49
c .getMethodName ( ) =
48
50
[
49
51
"+" , "/" , "basename" , "cleanpath" , "expand_path" , "join" , "realpath" ,
50
52
"relative_path_from" , "sub" , "sub_ext" , "to_path"
51
53
]
52
54
)
53
- )
54
- or
55
- exists ( TypeTracker t2 | result = pathnameInstance ( t2 ) .track ( t2 , t ) )
55
+ }
56
56
}
57
57
58
- private DataFlow:: Node pathnameInstance ( ) { pathnameInstance ( TypeTracker:: end ( ) ) .flowsTo ( result ) }
59
-
60
58
/** A call where the receiver is a `Pathname`. */
61
59
class PathnameCall extends DataFlow:: CallNode {
62
60
PathnameCall ( ) { this .getReceiver ( ) instanceof PathnameInstance }
0 commit comments