33private import codeql.ruby.AST
44private import codeql.ruby.ApiGraphs
55private import codeql.ruby.Concepts
6- private import codeql.ruby.DataFlow
76private import codeql.ruby.dataflow.FlowSummary
8- private import codeql.ruby.dataflow.internal.DataFlowDispatch
97private 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 }
0 commit comments