1
1
/**
2
2
* Bicep variable declarations.
3
3
*/
4
+
4
5
private import bicep
5
6
private import AstNodes
7
+ private import Calls
6
8
private import Idents
7
9
private import Stmts
8
10
private import codeql.bicep.controlflow.BasicBlocks as BasicBlocks
@@ -14,13 +16,198 @@ private import internal.VariableDeclaration
14
16
* A VariableDeclaration unknown AST node.
15
17
*/
16
18
class VariableDeclaration extends AstNode instanceof VariableDeclarationImpl {
17
- /**
18
- * Gets the identifier of the variable declaration.
19
- */
20
- Idents getIdentifier ( ) { result = VariableDeclarationImpl .super .getIdentifier ( ) }
21
-
22
- /**
23
- * Gets the initializer expression of the variable declaration.
24
- */
25
- Expr getInitializer ( ) { result = VariableDeclarationImpl .super .getInitializer ( ) }
19
+ /**
20
+ * Gets the identifier of the variable declaration.
21
+ */
22
+ Idents getIdentifier ( ) { result = VariableDeclarationImpl .super .getIdentifier ( ) }
23
+
24
+ /**
25
+ * Gets the initializer expression of the variable declaration.
26
+ */
27
+ Expr getInitializer ( ) { result = VariableDeclarationImpl .super .getInitializer ( ) }
28
+ }
29
+
30
+ private predicate variableDecl ( AstNode node , string name ) {
31
+ exists ( ParameterDeclaration param |
32
+ param .getName ( ) = name and
33
+ node = param
34
+ )
35
+ or
36
+ exists ( VariableDeclaration vardelc |
37
+ vardelc .getIdentifier ( ) .getName ( ) = name and
38
+ node = vardelc
39
+ )
40
+ or
41
+ exists ( OutputDeclaration output |
42
+ output .getIdentifier ( ) .getName ( ) = name and
43
+ node = output
44
+ )
45
+ }
46
+
47
+ /**
48
+ * Variable represents a variable defination.
49
+ */
50
+ class Variable extends MkVariable {
51
+ private AstNode node ;
52
+ private string name ;
53
+
54
+ Variable ( ) { this = MkVariable ( node , name ) }
55
+
56
+ string getName ( ) { result = name }
57
+
58
+ string toString ( ) { result = "Variable[" + name + "]" }
59
+
60
+ AstNode getAstNode ( ) { result = node }
61
+
62
+ /**
63
+ * Get the location of this variable.
64
+ */
65
+ Location getLocation ( ) { result = node .getLocation ( ) }
66
+
67
+ /**
68
+ * Geta the inner variable of this variable.
69
+ */
70
+ VariableAccess getAnAccess ( ) { result .getVariable ( ) = this }
71
+
72
+ /**
73
+ * Gets the type of this variable, if any.
74
+ */
75
+ Type getType ( ) {
76
+ result = this .getParameter ( ) .getType ( )
77
+ or
78
+ result = this .getOutput ( ) .getType ( )
79
+ }
80
+
81
+ /**
82
+ * Gets the parameter of this variable, if any.
83
+ */
84
+ ParameterDeclaration getParameter ( ) {
85
+ exists ( ParameterDeclaration param |
86
+ param .getName ( ) = this .getName ( ) and
87
+ param .getEnclosingCfgScope ( ) = this .getEnclosingCfgScope ( ) and
88
+ result = param
89
+ )
90
+ }
91
+
92
+ /**
93
+ * Gets the variable declaration of this variable, if any.
94
+ */
95
+ OutputDeclaration getOutput ( ) {
96
+ exists ( OutputDeclaration output |
97
+ output .getIdentifier ( ) .getName ( ) = this .getName ( ) and
98
+ output .getEnclosingCfgScope ( ) = this .getEnclosingCfgScope ( ) and
99
+ result = output
100
+ )
101
+ }
102
+
103
+ /**
104
+ * Gets the enclosing scope of this variable, if any.
105
+ */
106
+ CfgScope getEnclosingCfgScope ( ) { result = node .getEnclosingCfgScope ( ) }
107
+
108
+ // Expr getInitializer() { }
109
+ string getAPrimaryQlClass ( ) { result = "Variable" }
110
+ }
111
+
112
+ private predicate access ( AstNode node , Variable v , string name ) {
113
+ exists ( Identifier ident |
114
+ ident .getName ( ) = name and
115
+ // Make sure they are not in a declare statement
116
+ not ident .getParent ( ) instanceof VariableDeclaration and
117
+ // not ident.getParent() instanceof ParameterDeclaration and
118
+ // not ident.getParent() instanceof OutputDeclaration and
119
+ // Make sure they are in the same scope
120
+ ident .getName ( ) = v .getName ( ) and
121
+ ident .getEnclosingCfgScope ( ) = v .getEnclosingCfgScope ( ) and
122
+ ident = node
123
+ )
124
+ }
125
+
126
+ /**
127
+ * VariableAccess is a class that represents the access to a variable.
128
+ */
129
+ class VariableAccess extends MkVariableAccess , TVariableAccess {
130
+ private string name ;
131
+ private AstNode node ;
132
+ private Variable v ;
133
+
134
+ VariableAccess ( ) { this = MkVariableAccess ( node , v , name ) }
135
+
136
+ string getName ( ) { result = name }
137
+
138
+ AstNode getAstNode ( ) { result = node }
139
+
140
+ Variable getVariable ( ) { result = v }
141
+
142
+ string toString ( ) { result = "VariableAccess[" + name + "]" }
143
+
144
+ /**
145
+ * Get the location of this variable.
146
+ */
147
+ Location getLocation ( ) { result = node .getLocation ( ) }
148
+
149
+ /**
150
+ * Gets the type of this variable, if any.
151
+ */
152
+ Type getType ( ) { result = this .getVariable ( ) .getType ( ) }
153
+
154
+ /**
155
+ * Gets the enclosing scope of this variable, if any.
156
+ */
157
+ CfgScope getEnclosingCfgScope ( ) { result = v .getEnclosingCfgScope ( ) }
158
+
159
+ string getAPrimaryQlClass ( ) { result = "VariableAccess" }
26
160
}
161
+
162
+ class VariableWriteAccess extends VariableAccess {
163
+ VariableWriteAccess ( ) {
164
+ // Parameter
165
+ this .getAstNode ( ) .getParent ( ) instanceof ParameterDeclaration
166
+ or
167
+ // SET
168
+ this .getAstNode ( ) .getParent ( ) instanceof VariableDeclaration
169
+ or
170
+ // Output
171
+ this .getAstNode ( ) .getParent ( ) instanceof OutputDeclaration
172
+ }
173
+
174
+ override string getAPrimaryQlClass ( ) { result = "VariableWrite" }
175
+ }
176
+
177
+ class VariableReadAccess extends VariableAccess {
178
+ VariableReadAccess ( ) { not this instanceof VariableWriteAccess }
179
+
180
+ override string getAPrimaryQlClass ( ) { result = "VariableRead" }
181
+ }
182
+
183
+ /**
184
+ * Holds if the variable is written too.
185
+ */
186
+ // private predicate variableWrite(Variable node) {
187
+ // exists(Parameter param |
188
+ // param.getName() = node.getName() and
189
+ // param.getEnclosingCfgScope() = node.getEnclosingCfgScope()
190
+ // )
191
+ // }
192
+ cached
193
+ private module Cached {
194
+ cached
195
+ newtype TVariable =
196
+ TResource ( Resource resource , string name ) { resource .getName ( ) = name } or
197
+ TVariableDecl ( VariableDeclaration varDecl , string name ) {
198
+ varDecl .getIdentifier ( ) .getName ( ) = name
199
+ } or
200
+ TParameter ( ParameterDeclaration param , string name ) { param .getName ( ) = name } or
201
+ TOutput ( OutputDeclaration output , string name ) { output .getIdentifier ( ) .getName ( ) = name } or
202
+ MkVariable ( AstNode definingNode , string name ) { variableDecl ( definingNode , name ) }
203
+
204
+ cached
205
+ newtype TVariableAccess =
206
+ TIdent ( Identifier ident , string name ) { ident .getName ( ) = name } or
207
+ MkVariableAccess ( AstNode node , Variable v , string name ) { variableAccess ( node , v , name ) }
208
+
209
+ cached
210
+ predicate variableAccess ( AstNode node , Variable v , string name ) { access ( node , v , name ) }
211
+ }
212
+
213
+ private import Cached
0 commit comments