Skip to content

Commit 0dd756d

Browse files
committed
PS: Add support for variables.
1 parent 11c84cc commit 0dd756d

File tree

1 file changed

+92
-6
lines changed
  • powershell/ql/lib/semmle/code/powershell/ast/internal

1 file changed

+92
-6
lines changed

powershell/ql/lib/semmle/code/powershell/ast/internal/TAst.qll

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,70 @@ private predicate mkSynthChild(SynthKind kind, Raw::Ast parent, ChildIndex i) {
1010
any(Synthesis s).child(parent, i, SynthChild(kind))
1111
}
1212

13+
string variableNameInScope(Raw::Ast n, Scope::Range scope) {
14+
scope = Raw::scopeOf(n) and
15+
(
16+
result = n.(Raw::VarAccess).getUserPath() and
17+
not scope.getAParameter().(Raw::PipelineByPropertyNameParameter).getName() = result and
18+
not result.toLowerCase() = ["_", "this", "false", "true", "null"] and
19+
not parameter(_, n, _, _) and
20+
not Raw::isEnvVariableAccess(n, _) and
21+
not Raw::isAutomaticVariableAccess(n, _)
22+
or
23+
any(Synthesis s).explicitAssignment(n, result, _)
24+
or
25+
any(Synthesis s).implicitAssignment(n, result)
26+
)
27+
}
28+
29+
private predicate scopeAssigns(Scope::Range scope, string name, Raw::Ast n) {
30+
(explicitAssignment(n, _) or implicitAssignment(n)) and
31+
name = variableNameInScope(n, scope)
32+
}
33+
34+
private predicate scopeDefinesParameterVariable(Scope::Range scope, string name) {
35+
exists(Raw::Parameter p |
36+
any(Synthesis s).implicitAssignment(p, name) and
37+
p.getScope() = scope
38+
)
39+
}
40+
41+
private predicate inherits(Scope::Range scope, string name, Scope::Range outer) {
42+
not scopeDefinesParameterVariable(scope, name) and
43+
(
44+
outer = scope.getOuterScope() and
45+
(
46+
scopeDefinesParameterVariable(outer, name)
47+
or
48+
exists(Raw::Ast n |
49+
scopeAssigns(outer, name, n) and
50+
n.getLocation().strictlyBefore(scope.getLocation())
51+
)
52+
)
53+
or
54+
inherits(scope.getOuterScope(), name, outer)
55+
)
56+
}
57+
58+
pragma[nomagic]
59+
private predicate hasScopeAndName(VariableImpl variable, Scope::Range scope, string name) {
60+
variable.getNameImpl() = name and
61+
scope = variable.getDeclaringScopeImpl()
62+
}
63+
64+
private predicate access(Raw::VarAccess va, VariableImpl v) {
65+
exists(string name, Scope::Range scope |
66+
pragma[only_bind_into](name) = variableNameInScope(va, scope)
67+
|
68+
hasScopeAndName(v, scope, name)
69+
or
70+
exists(Scope::Range declScope |
71+
hasScopeAndName(v, declScope, pragma[only_bind_into](name)) and
72+
inherits(scope, name, declScope)
73+
)
74+
)
75+
}
76+
1377
cached
1478
private module Cached {
1579
private predicate excludeStringConstExpr(Raw::StringConstExpr e) {
@@ -76,6 +140,22 @@ private module Cached {
76140
TTypeConstraint(Raw::TypeConstraint t) or
77141
TUnaryExpr(Raw::UnaryExpr u) or
78142
TUsingStmt(Raw::UsingStmt u) or
143+
TVariableReal(Scope::Range scope, string name, Raw::Ast n) {
144+
not n instanceof Raw::Parameter and // we synthesize all parameters
145+
n =
146+
min(Raw::Ast other |
147+
scopeAssigns(scope, name, other)
148+
|
149+
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
150+
)
151+
} or
152+
TVariableSynth(Raw::Ast scope, ChildIndex i) { mkSynthChild(VarSynthKind(_), scope, i) } or
153+
TVarAccessReal(Raw::VarAccess va, Variable v) { access(va, v) } or
154+
TVarAccessSynth(Raw::Ast parent, ChildIndex i, Variable v) {
155+
mkSynthChild(VarAccessRealKind(v), parent, i)
156+
or
157+
mkSynthChild(VarAccessSynthKind(v), parent, i)
158+
} or
79159
TWhileStmt(Raw::WhileStmt w) or
80160
TTypeNameExpr(Raw::TypeNameExpr t) or
81161
TUsingExpr(Raw::UsingExpr u) or
@@ -95,18 +175,18 @@ private module Cached {
95175
TNamedAttributeArgument or TNamedBlock or TPipeline or TPipelineChain or TPropertyMember or
96176
TRedirection or TReturnStmt or TScriptBlock or TScriptBlockExpr or TStmtBlock or
97177
TStringConstExpr or TSwitchStmt or TConditionalExpr or TThrowStmt or TTrapStmt or
98-
TTryStmt or TTypeDefinitionStmt or TTypeConstraint or TUsingStmt or
178+
TTryStmt or TTypeDefinitionStmt or TTypeConstraint or TUsingStmt or TVarAccessReal or
99179
TWhileStmt or TFunctionDefinitionStmt or TExpandableSubExpr or TMethod or TTypeNameExpr or
100-
TAttributedExpr or TUsingExpr or TThisExprReal or TParenExpr ;
180+
TAttributedExpr or TUsingExpr or TThisExprReal or TParenExpr or TVariableReal;
101181

102182
class TAstSynth =
103-
TExprStmtSynth or TFunctionSynth or TBoolLiteral or TNullLiteral or
104-
TEnvVariable or TTypeSynth or TAutomaticVariable;
183+
TExprStmtSynth or TFunctionSynth or TBoolLiteral or TNullLiteral or TVarAccessSynth or
184+
TEnvVariable or TTypeSynth or TAutomaticVariable or TVariableSynth;
105185

106186
class TExpr =
107187
TArrayExpr or TArrayLiteral or TOperation or TConstExpr or TConvertExpr or TErrorExpr or
108188
THashTableExpr or TIndexExpr or TInvokeMemberExpr or TCmd or TMemberExpr or TPipeline or
109-
TPipelineChain or TStringConstExpr or TConditionalExpr or
189+
TPipelineChain or TStringConstExpr or TConditionalExpr or TVarAccess or
110190
TExpandableStringExpr or TScriptBlockExpr or TExpandableSubExpr or TTypeNameExpr or
111191
TUsingExpr or TAttributedExpr or TIf or TBoolLiteral or TNullLiteral or TThisExpr or
112192
TEnvVariable or TAutomaticVariable or TParenExpr;
@@ -138,6 +218,8 @@ private module Cached {
138218

139219
class TLoopStmt = TDoUntilStmt or TDoWhileStmt or TForEachStmt or TForStmt or TWhileStmt;
140220

221+
class TVarAccess = TVarAccessReal or TVarAccessSynth;
222+
141223
class TLiteral = TBoolLiteral or TNullLiteral;
142224

143225
class TGotoStmt = TContinueStmt or TBreakStmt;
@@ -195,13 +277,15 @@ private module Cached {
195277
n = TTypeConstraint(result) or
196278
n = TUnaryExpr(result) or
197279
n = TUsingStmt(result) or
280+
n = TVarAccessReal(result, _) or
198281
n = TWhileStmt(result) or
199282
n = TFunctionDefinitionStmt(result) or
200283
n = TExpandableSubExpr(result) or
201284
n = TTypeNameExpr(result) or
202285
n = TMethod(result) or
203286
n = TAttributedExpr(result) or
204287
n = TUsingExpr(result) or
288+
n = TVariableReal(_, _, result)
205289
}
206290

207291
cached
@@ -224,9 +308,11 @@ private module Cached {
224308
result = TFunctionSynth(parent, i) or
225309
result = TBoolLiteral(parent, i) or
226310
result = TNullLiteral(parent, i) or
311+
result = TVarAccessSynth(parent, i, _) or
227312
result = TEnvVariable(parent, i) or
228313
result = TTypeSynth(parent, i) or
229-
result = TAutomaticVariable(parent, i)
314+
result = TAutomaticVariable(parent, i) or
315+
result = TVariableSynth(parent, i)
230316
}
231317

232318
cached

0 commit comments

Comments
 (0)