@@ -82,22 +82,65 @@ private module Stdlib {
8282
8383 /** Provides models for the `os.path` module */
8484 module path {
85- /** Gets a reference to the `os.path.join` function. */
86- private DataFlow:: Node join ( DataFlow:: TypeTracker t ) {
87- t .start ( ) and
88- result = DataFlow:: importNode ( "os.path.join" )
89- or
90- t .startInAttr ( "join" ) and
91- result = os:: path ( )
85+ /**
86+ * Gets a reference to the attribute `attr_name` of the `os.path` module.
87+ * WARNING: Only holds for a few predefined attributes.
88+ *
89+ * For example, using `attr_name = "join"` will get all uses of `os.path.join`.
90+ */
91+ private DataFlow:: Node path_attr ( DataFlow:: TypeTracker t , string attr_name ) {
92+ attr_name in [ "join" , "normpath" ] and
93+ (
94+ t .start ( ) and
95+ result = DataFlow:: importNode ( "os.path." + attr_name )
96+ or
97+ t .startInAttr ( attr_name ) and
98+ result = os:: path ( )
99+ )
92100 or
93- exists ( DataFlow:: TypeTracker t2 | result = join ( t2 ) .track ( t2 , t ) )
101+ // Due to bad performance when using normal setup with `path_attr(t2, attr_name).track(t2, t)`
102+ // we have inlined that code and forced a join
103+ exists ( DataFlow:: TypeTracker t2 |
104+ exists ( DataFlow:: StepSummary summary |
105+ path_attr_first_join ( t2 , attr_name , result , summary ) and
106+ t = t2 .append ( summary )
107+ )
108+ )
109+ }
110+
111+ pragma [ nomagic]
112+ private predicate path_attr_first_join (
113+ DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
114+ DataFlow:: StepSummary summary
115+ ) {
116+ DataFlow:: StepSummary:: step ( path_attr ( t2 , attr_name ) , res , summary )
117+ }
118+
119+ /**
120+ * Gets a reference to the attribute `attr_name` of the `os.path` module.
121+ * WARNING: Only holds for a few predefined attributes.
122+ *
123+ * For example, using `attr_name = "join"` will get all uses of `os.path.join`.
124+ */
125+ DataFlow:: Node path_attr ( string attr_name ) {
126+ result = path_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
94127 }
95128
96129 /** Gets a reference to the `os.path.join` function. */
97- DataFlow:: Node join ( ) { result = join ( DataFlow :: TypeTracker :: end ( ) ) }
130+ DataFlow:: Node join ( ) { result = path_attr ( "join" ) }
98131 }
99132 }
100133
134+ /**
135+ * A call to `os.path.normpath`.
136+ * See https://docs.python.org/3/library/os.path.html#os.path.normpath
137+ */
138+ private class NormpathCall extends PathNormalization:: Range , DataFlow:: CfgNode {
139+ override CallNode node ;
140+
141+ NormpathCall ( ) { node .getFunction ( ) = os:: path:: path_attr ( "normpath" ) .asCfgNode ( ) }
142+ }
143+
101144 /**
102145 * A call to `os.system`.
103146 * See https://docs.python.org/3/library/os.html#os.system
0 commit comments