6
6
private import python
7
7
private import semmle.python.dataflow.new.DataFlow
8
8
private import semmle.python.Concepts
9
+ private import semmle.python.ApiGraphs
9
10
10
11
/**
11
12
* Provides models for the `invoke` PyPI package.
@@ -16,102 +17,44 @@ private module Invoke {
16
17
// invoke
17
18
// ---------------------------------------------------------------------------
18
19
/** Gets a reference to the `invoke` module. */
19
- private DataFlow:: Node invoke ( DataFlow:: TypeTracker t ) {
20
- t .start ( ) and
21
- result = DataFlow:: importNode ( "invoke" )
22
- or
23
- exists ( DataFlow:: TypeTracker t2 | result = invoke ( t2 ) .track ( t2 , t ) )
24
- }
25
-
26
- /** Gets a reference to the `invoke` module. */
27
- DataFlow:: Node invoke ( ) { result = invoke ( DataFlow:: TypeTracker:: end ( ) ) }
28
-
29
- /**
30
- * Gets a reference to the attribute `attr_name` of the `invoke` module.
31
- * WARNING: Only holds for a few predefined attributes.
32
- */
33
- private DataFlow:: Node invoke_attr ( DataFlow:: TypeTracker t , string attr_name ) {
34
- attr_name in [ "run" , "sudo" , "context" , "Context" , "task" ] and
35
- (
36
- t .start ( ) and
37
- result = DataFlow:: importNode ( "invoke." + attr_name )
38
- or
39
- t .startInAttr ( attr_name ) and
40
- result = DataFlow:: importNode ( "invoke" )
41
- )
42
- or
43
- // Due to bad performance when using normal setup with `invoke_attr(t2, attr_name).track(t2, t)`
44
- // we have inlined that code and forced a join
45
- exists ( DataFlow:: TypeTracker t2 |
46
- exists ( DataFlow:: StepSummary summary |
47
- invoke_attr_first_join ( t2 , attr_name , result , summary ) and
48
- t = t2 .append ( summary )
49
- )
50
- )
51
- }
52
-
53
- pragma [ nomagic]
54
- private predicate invoke_attr_first_join (
55
- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
56
- ) {
57
- DataFlow:: StepSummary:: step ( invoke_attr ( t2 , attr_name ) , res , summary )
58
- }
59
-
60
- /**
61
- * Gets a reference to the attribute `attr_name` of the `invoke` module.
62
- * WARNING: Only holds for a few predefined attributes.
63
- */
64
- private DataFlow:: Node invoke_attr ( string attr_name ) {
65
- result = invoke_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
66
- }
20
+ API:: Node invoke ( ) { result = API:: moduleImport ( "invoke" ) }
67
21
68
22
/** Provides models for the `invoke` module. */
69
23
module invoke {
70
24
/** Gets a reference to the `invoke.context` module. */
71
- DataFlow :: Node context ( ) { result = invoke_attr ( "context" ) }
25
+ API :: Node context ( ) { result = invoke ( ) . getMember ( "context" ) }
72
26
73
27
/** Provides models for the `invoke.context` module */
74
28
module context {
75
29
/** Provides models for the `invoke.context.Context` class */
76
30
module Context {
77
31
/** Gets a reference to the `invoke.context.Context` class. */
78
- private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
79
- t .start ( ) and
80
- result = DataFlow:: importNode ( "invoke.context.Context" )
81
- or
82
- t .startInAttr ( "Context" ) and
83
- result = invoke:: context ( )
84
- or
85
- // handle invoke.Context alias
86
- t .start ( ) and
87
- result = invoke_attr ( "Context" )
32
+ API:: Node classRef ( ) {
33
+ result = API:: moduleImport ( "invoke" ) .getMember ( "context" ) .getMember ( "Context" )
88
34
or
89
- exists ( DataFlow :: TypeTracker t2 | result = classRef ( t2 ) . track ( t2 , t ) )
35
+ result = API :: moduleImport ( "invoke" ) . getMember ( "Context" )
90
36
}
91
37
92
- /** Gets a reference to the `invoke.context.Context` class. */
93
- DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
94
-
95
38
/** Gets a reference to an instance of `invoke.context.Context`. */
96
- private DataFlow:: Node instance ( DataFlow:: TypeTracker t ) {
39
+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
97
40
t .start ( ) and
98
- result . asCfgNode ( ) . ( CallNode ) . getFunction ( ) =
99
- invoke:: context:: Context:: classRef ( ) .asCfgNode ( )
100
- or
101
- t . start ( ) and
102
- exists ( Function func |
103
- func . getADecorator ( ) = invoke_attr ( "task" ) . asExpr ( ) and
104
- result . ( DataFlow :: ParameterNode ) . getParameter ( ) = func . getArg ( 0 )
41
+ (
42
+ result = invoke:: context:: Context:: classRef ( ) .getACall ( )
43
+ or
44
+ exists ( Function func |
45
+ func . getADecorator ( ) = invoke ( ) . getMember ( "task" ) . getAUse ( ) . asExpr ( ) and
46
+ result . ( DataFlow :: ParameterNode ) . getParameter ( ) = func . getArg ( 0 )
47
+ )
105
48
)
106
49
or
107
50
exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
108
51
}
109
52
110
53
/** Gets a reference to an instance of `invoke.context.Context`. */
111
- DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
54
+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
112
55
113
56
/** Gets a reference to the `run` or `sudo` methods on a `invoke.context.Context` instance. */
114
- private DataFlow:: Node instanceRunMethods ( DataFlow:: TypeTracker t ) {
57
+ private DataFlow:: LocalSourceNode instanceRunMethods ( DataFlow:: TypeTracker t ) {
115
58
t .startInAttr ( [ "run" , "sudo" ] ) and
116
59
result = invoke:: context:: Context:: instance ( )
117
60
or
@@ -120,7 +63,7 @@ private module Invoke {
120
63
121
64
/** Gets a reference to the `run` or `sudo` methods on a `invoke.context.Context` instance. */
122
65
DataFlow:: Node instanceRunMethods ( ) {
123
- result = instanceRunMethods ( DataFlow:: TypeTracker:: end ( ) )
66
+ instanceRunMethods ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result )
124
67
}
125
68
}
126
69
}
@@ -131,15 +74,10 @@ private module Invoke {
131
74
* - `invoke.run` or `invoke.sudo` functions (http://docs.pyinvoke.org/en/stable/api/__init__.html)
132
75
* - `run` or `sudo` methods on a `invoke.context.Context` instance (http://docs.pyinvoke.org/en/stable/api/context.html#invoke.context.Context.run)
133
76
*/
134
- private class InvokeRunCommandCall extends SystemCommandExecution:: Range , DataFlow:: CfgNode {
135
- override CallNode node ;
136
-
77
+ private class InvokeRunCommandCall extends SystemCommandExecution:: Range , DataFlow:: CallCfgNode {
137
78
InvokeRunCommandCall ( ) {
138
- exists ( DataFlow:: Node callFunction | node .getFunction ( ) = callFunction .asCfgNode ( ) |
139
- callFunction = invoke_attr ( [ "run" , "sudo" ] )
140
- or
141
- callFunction = invoke:: context:: Context:: instanceRunMethods ( )
142
- )
79
+ this = invoke ( ) .getMember ( [ "run" , "sudo" ] ) .getACall ( ) or
80
+ this .getFunction ( ) = invoke:: context:: Context:: instanceRunMethods ( )
143
81
}
144
82
145
83
override DataFlow:: Node getCommand ( ) {
0 commit comments